//; ---------------------------------------------------------------------------
//; Object 3C - smashable	wall (GHZ, SLZ)
//; ---------------------------------------------------------------------------

#include "smash.h"

#include "../../sprite.h"
#include "../../objectsystemNEWER.h"
#include "../../collision.h"

static object *obj;

//EXTERN DEFINITIONS HERE

#define player objects[0]
extern object *objects;

//from sonic.asm
word Smash_FragSpd1[16] = { 0x400,-0x500,	//; x-move speed,	y-move speed
		            0x600,-0x100,
		            0x600, 0x100,
		            0x400, 0x500,
		            0x600,-0x600,
		            0x800,-0x200,
		            0x800, 0x200,
		            0x600, 0x600
};

word Smash_FragSpd2[16] = { -0x600,-0x600,
		            -0x800,-0x200,
		            -0x800, 0x200,
		            -0x600, 0x600,
		            -0x400,-0x500,
		            -0x600,-0x100,
		            -0x600, 0x100,
		            -0x400, 0x500
};

//; ---------------------------------------------------------------------------
//; Animation script - (OBJECT)
//; ---------------------------------------------------------------------------


//; ---------------------------------------------------------------------------
//; Sprite mappings - (OBJECT)
//; ---------------------------------------------------------------------------

byte _left[41] = {   8,
		 0xE0, 5, 0,	0, 0xF0,
		 0xF0, 5, 0,	0, 0xF0,
		    0, 5, 0,    0, 0xF0,
		 0x10, 5, 0,	0, 0xF0,
		 0xE0, 5, 0,	4,    0,
		 0xF0, 5, 0,	4,    0,
		    0, 5, 0,    4,    0,
		 0x10, 5, 0,	4,    0
};
byte middle[41] = { 8,
		 0xE0, 5, 0,	4, 0xF0,
		 0xF0, 5, 0,	4, 0xF0,
		    0, 5, 0,    4, 0xF0,
		 0x10, 5, 0,	4, 0xF0,
		 0xE0, 5, 0,	4,    0,
		 0xF0, 5, 0,	4,    0,
		    0, 5, 0,    4,    0,
		 0x10, 5, 0,	4,    0
};
byte _right[41] = {  8,
		 0xE0, 5, 0,  4, 0xF0,
		 0xF0, 5, 0,  4, 0xF0,
		    0, 5, 0,  4, 0xF0,
		 0x10, 5, 0,  4, 0xF0,
		 0xE0, 5, 0,  8,    0,
		 0xF0, 5, 0,  8,    0,
		    0, 5, 0,  8,    0,
		 0x10, 5, 0,  8,    0
};

byte *Map_Smash[3] = { _left, middle, _right };

//==========

void (*Smash_Index[3])() = { Smash_Main, Smash_Solid, Smash_FragMove };

//OBJECT:					; XREF: Obj_Index
void SmashWall(object *_obj)
{
    obj = _obj;

    //moveq	#0,d0
    //move.b	obRoutine(a0),d0
    byte routine = obj->Routine/2;

    //move.w	Smash_Index(pc,d0.w),d1
    //jsr	Smash_Index(pc,d1.w)
    (*Smash_Index[routine])();

    //bra.w	RememberState
    RememberState(obj);
}

//; ===========================================================================

#define speed 0x30 //; Sonic's horizontal speed

//Smash_Main:	; Routine 0
void Smash_Main()
{
    //addq.b	#2,obRoutine(a0)
    obj->Routine = obj->Routine + 2;

    //move.l	#Map_Smash,obMap(a0)
    obj->Map = Map_Smash;

    //move.w	#$450F,obGfx(a0)
    obj->Gfx = 0x450F;

    //move.b	#4,obRender(a0)
    obj->Render = 4;

    //move.b	#$10,obActWid(a0)
    obj->ActionWidth = 0x10;

    //move.b	#4,obPriority(a0)
    obj->Priority = 4;

    //move.b	obSubtype(a0),obFrame(a0)
    obj->Frame = obj->Subtype;

    Smash_Solid();
}
		
//Smash_Solid:	; Routine 2
void Smash_Solid()
{
    //move.w	(v_player+obVelX).w,speed(a0) ; load Sonic's horizontal speed
    ptrsetobjvariableword(speed, obj, player.VelocityX)

      //move.w	#$1B,d1
    word width = 27;
	
    //move.w	#$20,d2
    word jumpHeight = 32;

    //move.w	#$20,d3
    word walkHeight = 32;

    //move.w	obX(a0),d4
    word xpos = obj->X;

    //bsr.w	SolidObject
    SolidObject(obj, width, jumpHeight, walkHeight, xpos);
 
    //btst	#5,obStatus(a0)	; is Sonic pushing against the wall?
    //bne.s	@chkroll	; if yes, branch
    if ((obj->Status & 32) != 32)
    {
        //@chkroll:
	//cmpi.b	#id_Roll,obAnim(a1) ; is Sonic rolling?
        //bne.s	@donothing	; if not, branch
        if (obj->Anim == id_Roll)
	{	
            //move.w	speed(a0),d0
            signed short hspeed = ptrgetobjvariableword(speed, obj);

	    //bpl.s	@chkspeed
            if (hspeed < 0)
		//neg.w	d0
                hspeed = -hspeed;

	    //@chkspeed:
	    //cmpi.w	#$480,d0	; is Sonic's speed $480 or higher?
            //bcs.s	@donothing	; if not, branch
            if (hspeed >= 0x480)
            {
		//move.w	speed(a0),obVelX(a1)
                player.VelocityX  = ptrgetobjvariableword(speed, obj);

		//addq.w	#4,obX(a1)
                player.X = player.X + 4;

		//lea	(Smash_FragSpd1).l,a4 ;	use fragments that move	right
                byte *fragments = (byte*)Smash_FragSpd1;

		//move.w	obX(a0),d0
                word blockX = obj->X;

		//cmp.w	obX(a1),d0	; is Sonic to the right	of the block?
                //bcs.s	@smash		; if yes, branch
                if (player.X <= blockX)
                {
		    //subq.w	#8,obX(a1)
                    player.X = player.X - 8;

		    //lea	(Smash_FragSpd2).l,a4 ;	use fragments that move	left
                    fragments = (byte*)Smash_FragSpd2;
                }

	        //@smash:
		//move.w	obVelX(a1),obInertia(a1)
                player.Inertia = player.VelocityX;

		//bclr	#5,obStatus(a0)
                obj->Status = obj->Status - (obj->Status & 32);

		//bclr	#5,obStatus(a1)
                player.Status = player.Status - (player.Status & 32);

		//moveq	#7,d1		; load 8 fragments
                long fragCount = 8;

		//move.w	#$70,d2
                word smashSpeed = 0x70;

		//bsr.s	SmashObject(object *obj, byte *fragData, long fragCount, word smashSpeed)
                SmashObject(obj, fragments, fragCount, smashSpeed); //??
            }
        }
    }
    
    //@donothing:
    //rts	
    //; ===========================================================================

}	

//Smash_FragMove:	; Routine 4
void Smash_FragMove()
{
    //bsr.w	SpeedToPos
    SpeedToPos(obj);

    //addi.w	#$70,obVelY(a0)	; make fragment	fall faster
    obj->VelocityY = obj->VelocityY + 0x70;

    //bsr.w	DisplaySprite
    DisplaySprite(obj);

    //tst.b	obRender(a0)
    if ((signed char)obj->Render > 0)
    {
        //bpl.w	DeleteObject
        DeleteObject(obj);
    }
}   //rts	
